package cn.org.processor.guestbook.api.util;

import cn.org.processor.guestbook.api.configuration.ReCaptchaConfig;
import com.alibaba.fastjson.JSONObject;
import lombok.extern.slf4j.Slf4j;
import org.apache.http.HttpEntity;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.boot.web.client.RestTemplateBuilder;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

@Component
@Slf4j
public class ReCaptchaUtil {
    private static final String API_URL = "https://www.recaptcha.net/recaptcha/api/siteverify";
    private final ReCaptchaConfig config;
    private final RestTemplateBuilder restTemplateBuilder;

    public ReCaptchaUtil(ReCaptchaConfig config, RestTemplateBuilder restTemplateBuilder) {
        this.config = config;
        this.restTemplateBuilder = restTemplateBuilder;
    }

    public boolean hasSecret() {
        return config.getSecret() != null && config.getSecret().length() != 0;
    }

    public Map request(String response, String remoteIp) {
        CloseableHttpClient httpclient = HttpClients.createDefault();
        HttpPost http;
        CloseableHttpResponse resp = null;
        try {
            Map<String, Object> data = new HashMap<>();
            data.put("secret", this.config.getSecret());
            data.put("response", response);
            data.put("remoteip", remoteIp);

            HttpEntity postEntity = new StringEntity(JSONObject.toJSONString(data));
            http = new HttpPost(API_URL);
            http.setEntity(postEntity);
            resp = httpclient.execute(http);

            ResponseEntity<Map> responseEntity = restTemplateBuilder.build()
                    .postForEntity(API_URL + "?secret={secret}&response={response}&remoteip={remoteip}",
                            data, Map.class, data);
            if (responseEntity.getBody() != null) {
                return responseEntity.getBody();
            }

            log.warn("reCAPTCHA response empty");
        } catch (Exception e) {
            log.error("reCAPTCHA Exception: " + e);
        } finally {
            try {
                if (resp != null) resp.close();
            } catch (IOException e) {
                log.warn("reCAPTCHA response close exception: " + e);
            }
        }

        return null;
    }

    public boolean verify(String response, String remoteIp) {
        Map request = this.request(response, remoteIp);

        if (request != null) {
            return (boolean) request.get("success");
        }

        return false;
    }
}
